package com.warm.web.handler;

import cn.dev33.satoken.exception.DisableServiceException;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.hutool.core.util.ObjectUtil;
import com.warm.core.constant.HttpStatus;
import com.warm.core.domain.R;
import com.warm.core.exception.JsonException;
import com.warm.core.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;
import org.noear.solon.validation.ValidatorException;

/**
 * 全局异常处理
 *
 * @author warm
 */
@Slf4j
@Component
public class GlobalExceptionFilter implements Filter {
    @Override
    public void doFilter(Context ctx, FilterChain chain) throws Throwable {
        try {
            chain.doFilter(ctx);
        } catch (Exception e) {
            // 不同异常返回不同状态码
            String path = ctx.path();
            R<Object> aj;
            if (e instanceof NotLoginException) {
                log.error("请求地址'{}',未登录'{}',无法访问系统资源" , path, e.getMessage());
                aj = R.fail(HttpStatus.UNAUTHORIZED, "未登录，无法访问系统资源");
            } else if (e instanceof NotRoleException) {
                log.error("请求地址'{}',角色权限校验失败'{}'" , path, e.getMessage());
                aj = R.fail(HttpStatus.FORBIDDEN, "没有访问权限，请联系管理员授权");
            } else if (e instanceof NotPermissionException) {
                log.error("请求地址'{}',权限校验失败'{}'" , path, e.getMessage());
                aj = R.fail(HttpStatus.FORBIDDEN, "没有访问权限，请联系管理员授权");
            } else if (e instanceof DisableServiceException ee) {
                log.error("请求地址'{}',角色权限校验失败'{}'" , path, "账号被封禁：" + ee.getDisableTime() + "秒后解封");
                aj = R.fail(HttpStatus.FORBIDDEN, "账号被封禁：" + ee.getDisableTime() + "秒后解封");
            } else if (e instanceof ValidatorException) {
                log.error("请求地址'{}',校验异常'{}'" , path, e.getMessage());
                aj = R.fail(e.getMessage(), null);
            } else if (e instanceof JsonException) {
                log.error("请求地址'{}',json处理异常'{}'" , path, e.getMessage());
                aj = R.fail(HttpStatus.FORBIDDEN, "json处理异常");
            } else if (e instanceof ServiceException ee) {
                log.error(e.getMessage(), e);
                Integer code = ee.getCode();
                aj = ObjectUtil.isNotNull(code) ? R.fail(code, ee.getMessage()) : R.fail(ee.getMessage(), null);
            } else if (e instanceof RuntimeException) {
                log.error("请求地址'{}',发生未知异常." , path, e);
                aj = R.fail(e.getMessage(), null);
            } else { // 普通异常, 输出：500 + 异常信息
                log.error("请求地址'{}',发生系统异常." , path, e);
                aj = R.fail("发生未知异常" , null);
            }

            ctx.render(aj);
        }
    }
}
